﻿using System;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using Object = UnityEngine.Object;

namespace Core.Runtime
{
    /// <summary>
    /// 管理跨场景持久化对象的创建、获取和销毁
    /// </summary>
    public static class PersistentObjects
    {
        private static readonly Dictionary<Type, PersistentObject> persistentObjects = new();
        private static Transform _root;

        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
        private static void Initialize()
        {
            if (_root != null) return;

            _root = new GameObject("[PersistentObjects]").transform;
            Object.DontDestroyOnLoad(_root.gameObject);
        }

        public static bool AddPersistentObject<T>(GameObject go = null, int priority = 0) where T : Component
        {
            var type = typeof(T);
            return AddPersistentObject(type, go, priority);
        }


        public static bool AddPersistentObject(Type type, GameObject go = null, int priority = 0)
        {
            if (persistentObjects.TryGetValue(type, out var persistentObject))
            {
                Debug.LogError($"{type}对象已存在");
                return false;
            }

            if (go == null)
                go = new GameObject(type.Name);
            go.transform.SetParent(_root);
            if (!go.GetComponent(type))
                go.AddComponent(type);
            persistentObjects.Add(type, new PersistentObject(priority, go));
            return true;
        }

        public static GameObject GetPersistentObject<T>() where T : Component
        {
            var type = typeof(T);
            return GetPersistentObject(type);
        }

        public static GameObject GetPersistentObject(Type type)
        {
            return persistentObjects.TryGetValue(type, out var persistentObject) ? persistentObject.GameObject : null;
        }

        public static T GetComponent<T>() where T : Component
        {
            var type = typeof(T);
            return GetComponent(type) as T;
        }

        public static Component GetComponent(Type type)
        {
            return persistentObjects.TryGetValue(type, out var persistentObject)
                ? persistentObject.GameObject.GetComponent(type)
                : null;
        }

        /// <summary>
        /// 释放指定持久化对象
        /// </summary>
        public static void ReleaseObject(Type type)
        {
            if (!persistentObjects.Remove(type, out var persistentObject)) return;
            if (persistentObject != null) Object.Destroy(persistentObject.GameObject);
        }

        /// <summary>
        /// 释放所有持久化对象
        /// </summary>
        public static void ReleaseAll()
        {
            // 按优先级升序排列（优先级高的最后销毁）
            var sortedObjects = persistentObjects.Values.OrderBy(p => p.Priority).ToList();

            foreach (var obj in sortedObjects)
            {
                if (obj?.GameObject != null)
                {
                    Object.Destroy(obj.GameObject);
                }
            }
            persistentObjects.Clear();
            if (_root != null)
            {
                Object.Destroy(_root.gameObject);
                _root = null;
            }
        }
    }
}